/**
 * 
 * 一、序列化过程
 * 是指把一个Java对象变成二进制内容，实质上就是一个byte[]数组。
 * 因为序列化后可以把 byte[]保存到文件中，或者把 byte[] 通过网络传输到远程（IO），这样，就相当于把 Java 对象存储到文件或者通过网络传输出去了。
 * <p>
 * 二、反序列化过程
 * 把一个二进制内容（也就是 byte[]数组）变回Java对象。有了反序列化，保存到文件中的byte[]数组又可以 “变回”Java 对象，或者从网络上读取 byte[] 并把它“变回”Java 对象。
 * <p>
 * > 以下是一些使用序列化的示例：
 * 以面向对象的方式将数据存储到磁盘上的文件，例如，Redis 存储 Student 对象的列表。
 * 将程序的状态保存在磁盘上，例如，保存游戏状态。
 * 通过网络以表单对象形式发送数据，例如，在聊天应用程序中以对象形式发送消息。
 * <p>
 * 一个Java对象要能序列化，必须实现一个特殊的`java.io.Serializable接口`，它的定义如下：
 * <p>
 * Serializable接口没有定义任何方法，它是一个空接口。我们把这样的空接口称为标记接口（Marker Interface），实现了标记接口的类仅仅是给自身贴了个“标记”，并没有增加任何方法。
 * <p>
 * 三、序列化是如何工作的？
 * 当且仅当对象的类实现java.io.Serializable接口时，该对象才有资格进行序列化。可序列化是一个标记接口（不包含任何方法），该接口告诉Java虚拟机（JVM）该类的对象已准备好写入持久性存储或通过网络进行读取。
 * 默认情况下，JVM 负责编写和读取可序列化对象的过程。序列化/反序列化功能通过对象流类的以下两种方法公开：
 * 1、ObjectOutputStream.writeObject（Object）：将可序列化的对象写入输出流。如果要序列化的某些对象未实现Serializable 接口，则此方法将引发NotSerializableException。
 * 2、ObjectInputStream.readObject（）：从输入流读取，构造并返回一个Object对象。如果找不到序列化对象的类，则此方法将引发ClassNotFoundException。
 * 如果序列化使用的类有问题，则这两种方法都将引发InvalidClassException，如果发生 I / O 错误，则将引发IOException。无论NotSerializableException和InvalidClassException是子类IOException异常。
 * <p>
 * 四、什么是serialVersionUID常数？
 * serialVersionUID是一个常数，用于唯一标识可序列化类的版本，从输入流构造对象时，JVM在反序列化过程中检查此常数。
 * 如果正在读取的对象的serialVersionUID与类中指定的序列号不同，则JVM抛出InvalidClassException。这是为了确保正在构造的对象与具有相同serialVersionUID的类兼容。
 * 请注意，serialVersionUID是可选的。这意味着如果您不显式声明Java编译器，它将生成一个。
 * 那么，为什么要显式声明serialVersionUID呢？
 * 原因是：自动生成的serialVersionUID是基于类的元素（成员变量，方法，构造函数等）计算的。如果这些元素之一发生更改，serialVersionUID也将更改。
 * 1、您编写了一个程序，将Student类的某些对象存储到文件中。Student类没有显式声明的serialVersionUID。
 * 2、有时，您更新了Student 类（例如，添加了一个新的私有方法），现在自动生成的serialVersionUID 也被更改了。
 * 3、您的程序无法反序列化先前编写的Student对象，因为那里的serialVersionUID不同。JVM抛出InvalidClassException。
 * <p>
 * 五、那你知道什么是瞬时变量么？
 * 在上面的Student类中，您看到成员变量age被标记为transient，对吗？JVM在序列化过程中跳过瞬态变量。这意味着在序列化对象时不会存储age变量的值。
 *
 * @author guodd
 * @version 1.0 use jdk 1.8
 */
package ch03_oothinking.serializable;